<template>
<div class="left-box" ref="expList" id="expList">
    <div class="search-wrap search-inpt">
        <el-input clearable placeholder="搜索" v-model="filterText">
            <i slot="prefix" class="iconfont icon-sousuo"></i>
        </el-input>
        <el-dropdown trigger="click" @command="handleAdd">
            <i class="icon-add iconfont icon-new2"></i>
            <el-dropdown-menu slot="dropdown">
                <el-dropdown-item command="addExp">空白实验</el-dropdown-item>
                <el-dropdown-item command="toExpTemplate">模板实验</el-dropdown-item>
                <el-dropdown-item command="newFolder">文件夹</el-dropdown-item>
            </el-dropdown-menu>
        </el-dropdown>
    </div>
    <div class="scroll-bar">
        <el-tree default-expand-all @node-expand="nodeExpand" @node-collapse="nodeCollapse" v-loading="loading" element-loading-background="#f5f5f5" ref="tree" node-key="experimentId" :highlight-current="true" :data="treeData" :filter-node-method="filterNode" @node-click="handleClickNode">
            <span class="node-span-wrap" slot-scope="{data}" @contextmenu="handleContextMenu(data, $event)">
                <el-tooltip :open-delay="1000" :enterable="false" effect="dark" :content="data.isFolder ? data.catalogName : data.experimentName" placement="bottom">
                    <span class="tree-node-span">
                        <i class="iconfont tree-node-icon" :class="`${data.iconType}`"></i>
                        <span>{{data.isFolder ? data.catalogName : data.experimentName}}</span>
                    </span>
                </el-tooltip>
            </span>
        </el-tree>
    </div>
    <easy-cm tag="expList" :itemHeight="32" :itemSize="12" :list="cmList" @ecmcb="handleClickMenu" :underline="false" :arrow="true"></easy-cm>
    <confirm-dialog v-if="confirmObj.show" @save="reNameSave" :confirmObj="confirmObj"></confirm-dialog>
    <confirm-dialog v-if="newFolderObj.show" @save="newFolderSave" :confirmObj="newFolderObj">
        <div class="new-folder-confirm">
            <span class="folder-location">存储位置</span>
            <select-folder v-model="parentCatalogId" @input="clickNode"></select-folder>
        </div>
    </confirm-dialog>
    <confirm-dialog v-if="moveObj.show" @save="handleMove" :confirmObj="moveObj">
        <div class="new-folder-confirm">
            <span class="folder-location">存储位置</span>
            <select-folder v-model="parentCatalogId" @input="clickNode"></select-folder>
        </div>
    </confirm-dialog>
</div>
</template>

<script>
import {
    mapGetters,
    mapMutations
} from 'vuex'
import SelectFolder from '../SelectFolder'
import ConfirmDialog from '@/components/ConfirmDialog'
import {
    recursion
} from '@/js/tool'
export default {
    name: 'ExpList',
    components: {
        ConfirmDialog,
        SelectFolder
    },
    data () {
        return {
            parentCatalogId: null,
            moveObj: {
                title: '移动',
                show: false,
                noInput: true,
                size: 20
            },
            newFolderObj: {
                show: false,
                title: '新建文件夹',
                size: 20,
                value: '',
                leftTitle: '文件夹名称',
                placeholder: '请输入文件夹名称'
            },
            confirmObj: {
                show: false,
                title: '重命名',
                size: 50,
                value: ''
            },
            loading: false,
            treeData: [],
            addForm: {
                show: false,
                title: '新增实验',
                form: {
                    experimentName: '',
                    description: ''
                }
            },
            contexMenuItem: {},
            filterText: '',
            cmList: [],
            cmList1: [
                {
                    text: '打开',
                    icon: 'iconfont icon-tianjiazhushi'
                },
                {
                    text: '复制',
                    icon: 'iconfont icon-fuzhi'
                },
                {
                    text: '重命名',
                    icon: 'iconfont icon-zhongmingming'
                },
                {
                    text: '删除',
                    icon: 'iconfont icon-shanchu'
                },
                {
                    text: '移动',
                    icon: 'iconfont icon-yidong'
                }
            ],
            cmList2: [
                {
                    text: '新建文件夹',
                    icon: 'iconfont icon-xinjianwenjianjia'
                },
                {
                    text: '新建空白实验',
                    icon: 'iconfont icon-report-experiment'
                },
                {
                    text: '新建模板实验',
                    icon: 'iconfont icon-xinjianmobanshiyan'
                },
                {
                    text: '重命名',
                    icon: 'iconfont icon-zhongmingming'
                },
                {
                    text: '删除',
                    icon: 'iconfont icon-shanchu'
                },
                {
                    text: '移动',
                    icon: 'iconfont icon-yidong'
                }
            ],
            cmList3: [
                {
                    text: '新建文件夹',
                    icon: 'iconfont icon-xinjianwenjianjia'
                },
                {
                    text: '新建空白实验',
                    icon: 'iconfont icon-report-experiment'
                },
                {
                    text: '新建模板实验',
                    icon: 'iconfont icon-xinjianmobanshiyan'
                }
            ]
        }
    },
    watch: {
        removeExp (val) {
            if (val) {
                this.init()
            }
        },
        newExp (val) {
            this.init(val)
        },
        $route (val) {
            const id = val.params.experimentId
            id && this.init(id)
        },
        experimentId () {
            this.setId()
        },
        filterText (val) {
            this.$refs.tree.filter(val)
        },
        // 用于监听实验列表
        updateExp () {
            this.init()
        }
    },
    created () {
        const id = this.$route.params.experimentId
        this.init(id)
        let expId = localStorage.getItem('toExpId')
        if (expId) {
            setTimeout(() => {
                this.init(expId)
                localStorage.removeItem('toExpId')
            }, 1000)
        }
    },
    computed: {
        ...mapGetters({
            projectId: 'common/getProjectId',
            experimentId: 'common/getExperimentId',
            updateExp: 'common/getUpdateExp',
            newExp: 'common/getNewExp',
            removeExp: 'common/getRemoveExp'
        })
    },
    methods: {
        ...mapMutations({
            setCanvasLoading: 'common/setCanvasLoading',
            setShowNodeProp: 'common/setShowNodeProp',
            setRemoveCanvasExp: 'common/setRemoveCanvasExp',
            setExperimentId: 'common/setExperimentId',
            setCurrentExpInfo: 'common/setCurrentExpInfo'
        }),
        clickNode (val) {
            this.parentCatalogId = val
        },
        addExp (parentCatalogId) {
            this.$emit('addExp', !parentCatalogId ? null : parentCatalogId)
        },
        toExpTemplate () {
            this.$router.push('/expTemplate')
        },
        newFolder (parentCatalogId) {
            this.parentCatalogId = !parentCatalogId ? null : parentCatalogId
            this.newFolderObj.value = ''
            this.newFolderObj.show = true
        },
        handleContextMenu (data, e) {
            const { isFolder, iconType, catalogId } = data
            if (catalogId === -1 && isFolder) {
                this.cmList = this.cmList3
            } else {
                if (iconType === 'icon-moxing_shiyan') {
                    this.cmList = this.cmList1
                }
                if (iconType === 'icon-catalog-open' || iconType === 'icon-catalog-close') {
                    this.cmList = this.cmList2
                }
            }
            this.$easycm(e, this.$root, 'expList')
            this.contexMenuItem = data
        },
        handleAdd (val) {
            this[val]()
        },
        nodeCollapse (item) {
            if (item.isFolder) {
                item.iconType = 'icon-catalog-close'
            }
        },
        nodeExpand (item) {
            if (item.isFolder) {
                item.iconType = 'icon-catalog-open'
            }
        },
        handleClickNode (item, node) {
            if (this.experimentId === item.experimentId) {
                return
            }
            if (item.iconType === 'icon-moxing_shiyan') {
                this.setCanvasLoading(true)
                this.setShowNodeProp(false)
                this.setExperimentId(item.experimentId)
                this.$emit('addTab', item)
            }
        },
        handleCopyExp (item) {
            this.$emit('copyExp', item)
        },
        filterNode (value, data) {
            if (!value) return true
            return data[data.isFolder ? 'catalogName' : 'experimentName'].indexOf(value) !== -1
        },
        handleMove () {
            let flag = this.cmList.length === 6
            const { experimentName, catalogId, experimentId } = this.contexMenuItem
            if (this.parentCatalogId === catalogId) {
                this.$message.error('禁止移动到自己的子目录下!')
                this.moveObj.show = false
                return false
            }
            let params = !flag ? {
                projectId: this.projectId,
                experimentId,
                experimentName,
                catalogId: this.parentCatalogId
            } : {
                projectId: this.projectId,
                catalogId,
                parentCatalogId: this.parentCatalogId
            }
            let url = !flag ? '/experiment/updateExperiment' : '/experiment/catalog/moveCatalog'
            this.$post(url, params).then(res => {
                if (res) {
                    this.$message.success('移动成功')
                    this.moveObj.show = false
                    this.init()
                }
            })
        },
        handleRemove (str) {
            const { catalogName, experimentName, catalogId, experimentId } = this.contexMenuItem
            this.$confirm(`确定要删除${str}<span>[${str === '实验' ? experimentName : catalogName}]</span>吗？</br>删除后，实验下的模型也将一并被删除，请确认后再进行删除。`, '提示', {
                confirmButtonText: '确 定',
                cancelButtonText: '取 消',
                dangerouslyUseHTMLString: true,
                type: 'warning'
            }).then(() => {
                let flag = str === '文件夹'
                let params = flag ? {
                    projectId: this.projectId,
                    catalogId: catalogId
                } : {
                    projectId: this.projectId,
                    experimentIds: [experimentId]
                }
                let url = flag ? '/experiment/catalog/deleteCatalog' : '/experiment/deleteExperiment'
                this.$post(url, params).then(res => {
                    if (res) {
                        this.$message.success('删除成功')
                        this.init()
                        !flag && this.setRemoveCanvasExp(experimentId)
                    }
                })
            }).catch(() => {})
        },
        newFolderSave (value) {
            this.$post('/experiment/catalog/createCatalog', {
                projectId: this.projectId,
                catalogName: value,
                parentCatalogId: this.parentCatalogId
            }).then(res => {
                if (res) {
                    this.newFolderObj.show = false
                    this.$message.success('保存成功')
                    this.init()
                }
            })
        },
        reNameSave (experimentName) {
            let flag = this.cmList.length === 6
            const { experimentId, description, catalogId } = this.contexMenuItem
            let params = !flag ? {
                projectId: this.projectId,
                experimentId,
                experimentName,
                description
            } : {
                projectId: this.projectId,
                catalogName: experimentName,
                catalogId
            }
            let url = !flag ? '/experiment/updateExperiment' : '/experiment/catalog/renameCatalog'
            this.$post(url, params).then(res => {
                if (res) {
                    this.confirmObj.show = false
                    this.$message.success('保存成功')
                    this.init()
                    !flag && this.$emit('updateTab', { experimentId, experimentName })
                }
            })
        },
        reName (str) {
            const {
                experimentName,
                catalogName
            } = this.contexMenuItem
            this.confirmObj = {
                show: true,
                title: '重命名',
                placeholder: `请输入${str}名称`,
                size: 50,
                value: str === '文件夹' ? catalogName : experimentName
            }
        },
        // 实验列表，右键菜单
        handleClickMenu ([n]) {
            let len = this.cmList.length
            if (len === 6 || len === 3) {
                switch (n) {
                    case 0:
                        // 新建文件夹
                        this.newFolder(this.contexMenuItem.catalogId)
                        break
                    case 1:
                        // 新建空白实验
                        this.addExp(this.contexMenuItem.catalogId)
                        break
                    case 2:
                        // 新建模板实验
                        this.toExpTemplate()
                        break
                    case 3:
                        // 重命名
                        this.reName('文件夹')
                        break
                    case 4:
                        // 删除
                        this.handleRemove('文件夹')
                        break
                    case 5:
                        // 移动
                        this.moveObj.show = true
                        break
                }
            }
            if (len === 5) {
                switch (n) {
                    case 0:
                        // 打开
                        this.handleClickNode(this.contexMenuItem)
                        break
                    case 1:
                        // 复制
                        this.handleCopyExp(this.contexMenuItem)
                        break
                    case 2:
                        // 重命名
                        this.reName('实验')
                        break
                    case 3:
                        // 删除
                        this.handleRemove('实验')
                        break
                    case 4:
                        // 移动
                        this.moveObj.show = true
                        break
                }
            }
        },
        setId () {
            this.$nextTick(() => {
                if (this.experimentId) {
                    this.$refs.tree.setCurrentKey(this.experimentId)
                    this.setCurrentExpInfo(this.getExpInfo(this.experimentId))
                } else {
                    let dom = this.$refs.tree.$el.getElementsByClassName('is-current')[0]
                    dom && dom.classList.remove('is-current')
                }
            })
        },
        getExpInfo (experimentId) {
            return recursion(this.treeData, 'experimentId', experimentId - 0)
        },
        clickItem (experimentId) {
            this.handleClickNode(this.getExpInfo(experimentId))
        },
        init (experimentId) {
            this.loading = true
            const parmas = {
                keyword: '',
                projectId: this.projectId,
                catalogOnly: false
            }
            this.$post('/experiment/catalog/queryExperimentCatalog', parmas).then(res => {
                if (res) {
                    this.treeData = [res.root]
                    this.$emit('empty', res.root)
                    experimentId && this.clickItem(experimentId)
                    this.setId()
                }
            }).finally(() => {
                this.loading = false
            })
        }
    }
}
</script>
<style lang="less">
    #expList {
        .icon-add {
            cursor: pointer;
            font-size: 20px;
            margin-left: 5px;
        }
        .search-wrap {
            display: flex;
            align-items: center;
            justify-content: space-between;
        }
    }
</style>
